package com.ncu.spring.core;

import java.util.Arrays;
import java.util.Comparator;
import java.util.List;


/**
 *   1.OrderComparator：排序器基类,实现了Comparator.
 *   2.排序规则仅支持PriorityOrdered、Ordered，不支持@Order。
 *   3.用来设置环绕通知的执行顺序
 *   4.实现单例模式：操作都是通过创建的常量INSTANCE 这个常量创建就不可更改 相当于单例类
 *   5.排序规则：
 *      实现PriorityOrdered接口 优先执行
 *      实现Ordered接口的优先执行 (当然getOrder()方法要小于Integer.MAX)
 *      为空或者没有实现上诉两个接口的优先级最低
 */
public class OrderComparator implements Comparator<Object> {

    public static final OrderComparator INSTANCE = new OrderComparator();

    public static void sort(List<?> list) {
        if (list.size() > 1) {
            list.sort(INSTANCE);
        }
    }

    public static void sort(Object[] array) {
        if (array.length > 1) {
            Arrays.sort(array, INSTANCE);
        }
    }

    //排序规则
    @Override
    public int compare(Object o1, Object o2) {
        //判断这两个对象是不是PriorityOrdered的实现类对象
        boolean p1 = o1 instanceof PriorityOrdered;
        boolean p2 = o2 instanceof PriorityOrdered;
        //是PriorityOrdered的对象优先级更高 排更前面
        if (p1 && !p2) {
            return -1; //表示o1小于o2,o1要排在o2的前面
        } else if (!p1 && p2) {
            return 1;  //表示o1大于o2,o2要排在o1的前面
        }
        //两者是或者两者都不是
        int order1 = getOrder(o1); //采用getOrder()判断
        int order2 = getOrder(o2);
        // 不要直接写 order1 - order2，会照成数值溢出问题 因为值都是Integer的最大或者最小
        // 使用 Integer.compare 避免溢出
        return Integer.compare(order1, order2);
    }

    private int getOrder(Object obj) {
        if (obj == null) { //该对象为空就最低优先级
            return Ordered.LOWEST_PRECEDENCE;
        }
        if (obj instanceof Ordered) { //实现Ordered 就去执行该实现类的Ordered方法
            return ((Ordered) obj).getOrder();
        } else { //该对象没有实现Ordered接口 也是最低优先级
            return Ordered.LOWEST_PRECEDENCE;
        }
    }
}
